package com.db.priceApp.service;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Arrays;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;

import com.db.priceApp.domain.InstrumentList;
import com.db.priceApp.domain.clientDataBasa.ClientProfile;
import com.db.priceApp.domain.clientDataBasa.ClientsBasa;
import com.db.priceApp.network.Server;
import com.db.priceApp.network.protocol.Message;

public class InstrumentApplication {

	private static final int DEFAULT_THREAD_POOL_SIZE = 4;

	public static void main(String[] args) {
		Runnable worker;
		InstrumentList instruments = new InstrumentList();
		ReaderFromFile fileReader = new ReaderFromFile(instruments);
		
		if (args.length > 0) {
			try {
				fileReader.readInstrumentListFromFile(args[0]);
				
			} catch (FileNotFoundException e) {
				
				instruments.setDefaultInstrumentList();
			} catch (IOException e) {
				
				instruments.setDefaultInstrumentList();
			}
		} else {
			
			instruments.setDefaultInstrumentList();
		}
		
		BlockingQueue<Message> clientRequests = new LinkedBlockingQueue<Message>();
		ClientsBasa clientBasa = new ClientsBasa(
				new ConcurrentHashMap<String, ClientProfile>());

		ExecutorService executor = Executors
				.newFixedThreadPool(DEFAULT_THREAD_POOL_SIZE);

		int numOfWorkers = (DEFAULT_THREAD_POOL_SIZE - 2)/2;

		for (int i = 0; i < numOfWorkers; i++) {
			worker = new PriceSender(instruments, clientBasa, numOfWorkers);
			executor.execute(worker);
		}

		for (int i = numOfWorkers; i < DEFAULT_THREAD_POOL_SIZE - 2; i++) {
			worker = new ClientRequestsProcessor(clientRequests,
					instruments.getInstrumentList(), clientBasa);
			executor.execute(worker);
		}

		
		worker = new PriceGenerator(instruments);
		executor.execute(worker);
		
		worker = new Server(clientRequests, clientBasa);
		executor.execute(worker);
		
		executor.shutdown();
		
	}
}
